package de.tuhh.simsearch.util;

import java.util.HashSet;
import java.util.Set;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import de.tuhh.simsearch.constants.Constants;
import de.tuhh.simsearch.dto.GroupDTO;
import de.tuhh.simsearch.dto.PreferenceDTO;
import de.tuhh.simsearch.dto.UserDTO;
import de.tuhh.simsearch.model.persistence.usermgmt.eao.interfaces.UserMgmtEAOInterface;
import de.tuhh.simsearch.model.persistence.usermgmt.entities.GroupEntity;
import de.tuhh.simsearch.model.persistence.usermgmt.entities.PreferenceEntity;
import de.tuhh.simsearch.model.persistence.usermgmt.entities.UserEntity;

/**
 * Conversion class, converts user management entity objects and into data transfer objects and vice versa.
 * 
 * @author SimSearch 1
 * 
 * @see UserEntity
 * @see GroupEntity
 * @see PreferenceEntity
 * @see UserDTO
 * @see GroupDTO
 * @see PreferenceDTO
 * 
 */
@Stateless
public class Conversion {

  /**
   * The Entity Access Object to be used to access database
   */
  @EJB UserMgmtEAOInterface usrmEAO;

  /**
   * Converts user entity objects to user dto
   * 
   * @param entity
   *          the entity object to convert
   * @return the resulting user dto
   */
  public UserDTO fromEntity(UserEntity entity) {

    UserDTO dto = new UserDTO();
    dto.setName(entity.getName());

    if (entity.getCreatedGroups() != null && !entity.getCreatedGroups().isEmpty()) {
      Set<String> createdgroups = new HashSet<String>();
      for (GroupEntity g : entity.getCreatedGroups()) {
        createdgroups.add(g.getName());
      }
      dto.setCreatedGroups(createdgroups);
    }

    if (entity.getJoinedGroups() != null && !entity.getJoinedGroups().isEmpty()) {
      Set<String> joinedgroups = new HashSet<String>();
      for (GroupEntity g : entity.getJoinedGroups()) {
        joinedgroups.add(g.getName());
      }
      dto.setJoinedGroups(joinedgroups);
    }

    if (entity.getPreferences() != null && !entity.getPreferences().isEmpty()) {
      Set<PreferenceTuple> prefs = new HashSet<PreferenceTuple>();
      for (PreferenceEntity p : entity.getPreferences()) {
        prefs.add(new PreferenceTuple(p.getName(), Constants.contentIdDescMap.get(p.getContentID())));
      }
      dto.setPreferences(prefs);
    }

    if (entity.getRequestedGroups() != null && !entity.getRequestedGroups().isEmpty()) {
      Set<String> groups = new HashSet<String>();
      for (GroupEntity g : entity.getRequestedGroups()) {
        groups.add(g.getName());
      }
      dto.setRequestedGroups(groups);
    }

    return dto;
  }

  /**
   * Converts a group entity objtect into a group dto.
   * 
   * @param entity
   *          the entity to convert
   * @return the resulting dto
   */
  public GroupDTO fromEntity(GroupEntity entity) {

    Set<String> members = new HashSet<String>();
    GroupDTO dto = new GroupDTO(entity.getName(), entity.getAdministrator().getName());

    if (entity.getMembers() != null && !entity.getMembers().isEmpty()) {
      for (UserEntity u : entity.getMembers()) {
        members.add(u.getName());
      }
      dto.setUsers(members);
      members = new HashSet<String>();
    }

    if (entity.getPendingUsers() != null && !entity.getPendingUsers().isEmpty()) {
      for (UserEntity u : entity.getPendingUsers()) {
        members.add(u.getName());
      }
      dto.setPendingUsers(members);
    }

    return dto;
  }

  /**
   * Converts a preference entity objtect into a preference dto.
   * 
   * @param entity
   *          the entity to convert
   * @return the resulting dto
   */
  public PreferenceDTO fromEntity(PreferenceEntity entity) {

    PreferenceDTO dto = new PreferenceDTO();
    Set<String> subs = new HashSet<String>();
    dto.setContentType(Constants.contentIdDescMap.get(entity.getContentID()));
    dto.setName(entity.getName());

    if (entity.getPreferenceSubscriber() != null && !entity.getPreferenceSubscriber().isEmpty()) {
      for (UserEntity u : entity.getPreferenceSubscriber()) {
        subs.add(u.getName());
      }
    }

    dto.setPreferenceSubscriber(subs);

    return dto;
  }

  /**
   * Converts a user dto into a user entity object
   * 
   * @param dto
   *          the dto to contert
   * @return the resulting user entity object
   */
  public UserEntity fromDto(UserDTO dto) {

    UserEntity entity;

    if (usrmEAO.getUserEntity(dto.getName()) != null) {
      entity = usrmEAO.getUserEntity(dto.getName());
    } else {
      entity = new UserEntity(dto.getName());
    }

    if (dto.getCreatedGroups() != null && !dto.getCreatedGroups().isEmpty()) {
      for (String g : dto.getCreatedGroups()) {
        try {
          entity.addCreatedGroup(usrmEAO.getGroupEntity(g));
        } catch (NullPointerException e) {
          System.out.println("Could not add created group to entity");
          e.printStackTrace();
        }
      }
    }

    if (dto.getJoinedGroups() != null && !dto.getJoinedGroups().isEmpty()) {
      for (String g : dto.getJoinedGroups()) {
        try {
          entity.addJoinedGroup(usrmEAO.getGroupEntity(g));
        } catch (NullPointerException e) {
          System.out.println("Could not add joined group to entity");
          e.printStackTrace();
        }
      }
    }

    if (dto.getPreferences() != null && !dto.getPreferences().isEmpty()) {
      for (PreferenceTuple p : dto.getPreferences()) {
        try {
          entity.addPreference(usrmEAO.getPreferenceEntity(p.getPreferenceName(),
              Constants.descContentIdMap.get(p.getContentType())));
        } catch (NullPointerException e) {
          System.out.println("Could not add preference to entity");
          e.printStackTrace();
        }

      }

    }
    return entity;
  }

  /**
   * Converts group dtos into group entity objects
   * 
   * @param dto
   *          the dto to convert
   * @return the resulting group entity object
   */
  public GroupEntity fromDto(GroupDTO dto) {

    GroupEntity entity;

    if (usrmEAO.getGroupEntity(dto.getName()) != null) {
      entity = usrmEAO.getGroupEntity(dto.getName());
    } else {
      entity = new GroupEntity(dto.getName());
    }

    if (dto.getGrpAdmin() != null) {
      entity.setAdministrator(usrmEAO.getUserEntity(dto.getGrpAdmin()));
    }

    if (dto.getPendingUsers() != null) {
      for (String p : dto.getPendingUsers()) {
        try {
          entity.addPendingUser(usrmEAO.getUserEntity(p));
        } catch (NullPointerException e) {
          System.out.println("Could not add pending user to group");
          e.printStackTrace();
        }
      }
    }

    if (dto.getUsers() != null) {
      for (String u : dto.getUsers()) {
        try {
          entity.addMember(usrmEAO.getUserEntity(u));
        } catch (NullPointerException e) {
          System.out.println("Could not add user to group");
          e.printStackTrace();
        }
      }
    }

    return entity;
  }

  /**
   * Converts preference dtos into preference entities
   * 
   * @param dto
   *          the dto to convert
   * @return the resulting preference entity
   */
  public PreferenceEntity fromDto(PreferenceDTO dto) {

    PreferenceEntity entity;

    if (usrmEAO.getPreferenceEntity(dto.getName(), Constants.descContentIdMap.get(dto.getContentType())) != null) {
      entity = usrmEAO.getPreferenceEntity(dto.getName(), Constants.descContentIdMap.get(dto.getContentType()));

    } else {
      entity = new PreferenceEntity(dto.getName(), Constants.descContentIdMap.get(dto.getContentType()));
    }

    if (dto.getPreferenceSubscriber() != null) {
      for (String u : dto.getPreferenceSubscriber()) {
        try {
          entity.addPreferenceSubscriber(usrmEAO.getUserEntity(u));
        } catch (NullPointerException e) {
          System.out.println("Could not add preference subscriber to preference entity");
          e.printStackTrace();
        }
      }

    }

    return entity;
  }

}
